<template>
  <el-dialog
    title="用户注册"
    :visible.sync="dialogVisible"
    width="600px"
    center
    @close="close"
  >
    <el-form
      :model="form"
      ref="form"
      :rules="rules"
      label-width="80px"
      :inline="false"
      size="normal"
      label-position="left"
    >
      <el-form-item label="头像" prop="avatar">
        <el-upload
          class="avatar-uploader"
          :action="uploadUrl"
          :show-file-list="false"
          :data="option"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
        >
          <img v-if="imageUrl" :src="imageUrl" class="avatar" />
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </el-form-item>
      <el-form-item label="昵称" prop="username">
        <el-input v-model="form.username"></el-input>
      </el-form-item>
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="form.email"></el-input>
      </el-form-item>
      <el-form-item label="手机" prop="phone">
        <el-input v-model="form.phone"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input v-model="form.password"></el-input>
      </el-form-item>
      <el-row>
        <el-col :span="16" style="margin-right:15px">
          <el-form-item label="图形码" prop="code">
            <el-input v-model="form.code"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="7">
          <img
            :src="codeCaptcha"
            alt=""
            width="100%"
            height="40px"
            @click="chageCode"
          />
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="16" style="margin-right:15px">
          <el-form-item label="验证码" prop="rcode">
            <el-input v-model="form.rcode"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="7">
          <el-button size="default" style="width:100%" @click="getRcode"
            >获取用户验证码</el-button
          >
        </el-col>
      </el-row>
    </el-form>

    <span slot="footer" class="dialog-footer">
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="submit">确 定</el-button>
    </span>
  </el-dialog>
</template>
<script>
export default {
  name: 'register',
  data () {
    return {
      dialogVisible: false,
      codeCaptcha:
        process.env.VUE_APP_BASEURL + '/captcha?type=sendsms' /* 图形码地址 */,
      uploadUrl: process.env.VUE_APP_BASEURL + '/uploads' /* 头像上传的地址 */,
      imageUrl: '' /* 头像预览的地址 */,
      option: {} /* 上传头像时需要的额外参数 */,
      form: {
        username: '' /* 用户名 */,
        phone: '' /* 手机号 */,
        email: '' /* 邮箱 */,
        avatar: '' /* 头像地址 */,
        password: '' /* 密码 */,
        code: '' /* 图形码 */,
        rcode: '' /* 验证码 */
      },
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        phone: [
          {
            required: true,
            validator: (rule, value, callback) => {
              // 1.判断是否输入手机号
              if (!value) return callback(new Error('请输入手机号'))
              // 2.规定手机号的正则
              const reg = /^1[3-9][0-9]{9}$/
              // 3.判断输入的手机号是否符合这个正则
              if (!reg.test(value)) {
                return callback(new Error('手机号不合法'))
              }
              // 4.无论验证通不通过callback()都要执行
              callback()
            },
            trigger: 'blur'
          }
        ],
        email: [
          {
            required: true,
            validator: (rule, value, callback) => {
              // 1.判断是否输入邮箱
              if (!value) return callback(new Error('请输入邮箱'))
              // 2.规定邮箱的正则
              const reg = /^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}$/
              // 3.判断输入的邮箱是否符合这个正则
              if (!reg.test(value)) {
                return callback(new Error('邮箱不合法'))
              }
              // 4.无论验证通不通过callback()都要执行
              callback()
            },
            trigger: 'blur'
          }
        ],
        avatar: [{ required: true, message: '请上传头像', trigger: 'change' }],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 8, max: 16, message: '密码长度必须在8-16位', trigger: 'blur' }
        ],
        code: [
          { required: true, message: '请输入图形码', trigger: 'blur' },
          { min: 4, max: 4, message: '图形码长度必须是4位', trigger: 'blur' }
        ],
        rcode: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
      }
    }
  },
  methods: {
    // 头像上传后的操作
    handleAvatarSuccess (res, file) {
      // 1.判断头像上传是否成功
      if (res.code === 200) {
        // 2.实现图片预览
        this.imageUrl = URL.createObjectURL(file.raw)
        // 3.将上传成功后服务器返回的地址赋值给表单中的avatar
        this.form.avatar = res.data.file_path
      } else {
        // 4.上传失败提示用户
        this.$message({
          type: 'error',
          message: res.message,
          duration: 1000
        })
      }
    },
    // 头像上传前的操作
    beforeAvatarUpload (file) {
      // 1.携带额外参数
      this.option.image = file
      // 2.规定图片大小和格式
      const isJPG =
        file.type === 'image/jpeg' ||
        file.type === 'image/png' ||
        file.type === 'image/gif'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        this.$message.error('上传头像图片只能是 JPG | PNG | GIF格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
      }
      return isJPG && isLt2M
    },
    // 获取验证码
    async getRcode () {
      // 1.局部校验表单中的手机号和图形码
      let num = 0
      this.$refs.form.validateField(['phone', 'code'], valid => {
        // 事先准备一个计数器
        if (!valid) {
          num++
        }
      })
      // 2.判断两次校验是否都通过
      if (num === 2) {
        // 3.发送请求
        const res = await this.$axios.post('/sendsms', {
          phone: this.form.phone,
          code: this.form.code
        })
        // 4.判断请求是否成功
        if (res.code === 200) {
          // 5.提示用户
          this.$message({
            type: 'success',
            message: '验证码已发送~',
            duration: 1000
          })
          // 6.将服务器返回的验证码进行赋值
          this.form.rcode = res.data.captcha
        } else {
          // 7.请求失败也提示用户
          this.$message({
            type: 'error',
            message: res.message,
            duration: 1000
          })
          // 8.更换图形码
          this.chageCode()
        }
      }
    },
    // 更换图形码
    chageCode () {
      this.codeCaptcha =
        process.env.VUE_APP_BASEURL + '/captcha?type=sendsms&t=' + Date.now()
    },
    // 完成注册功能
    submit () {
      // 1.全局校验表单
      this.$refs.form.validate(async valid => {
        // 2.判断校验是否通过
        if (!valid) return
        // 3.发送注册请求
        const res = await this.$axios.post('/register', this.form)
        // 4.判断注册是否成功
        if (res.code === 200) {
          // 5.提示用户
          this.$message({
            type: 'success',
            message: '注册成功',
            duration: 1000
          })
          // 6.隐藏弹窗
          this.dialogVisible = false
        } else {
          // 7.注册失败也提示用户
          this.$message({
            type: 'error',
            message: res.message,
            duration: 1000
          })
        }
        // 8.无论注册成不成功都要更新图形码
        this.chageCode()
      })
    },
    // 关闭弹窗后的操作
    close () {
      // 1.清除表单内容
      this.$refs.form.resetFields()
      //   2.手动清除头像
      this.imageUrl = ''
    }
  }
}
</script>
<style>
.avatar-uploader {
  text-align: center;
}
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px !important;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>
